package View;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import javax.swing.Timer;

import java.awt.BorderLayout;
import javax.swing.JButton;

import Model.Fighter;
import Model.I_Interactable.Actions;
import Model.Player;
import Model.NPC.NPCType;
import Model.MarketPlace.MarketPlaceItem;
import Presenter.SpaceTravelPresenter;
import java.awt.FlowLayout;

public class SpaceTravelView extends JPanel {

	/**
	 * Create the panel.
	 */
	
	private final SpaceTravelPresenter presenter;

	/**
	 * 
	 */
	private final JLabel prompt;
	
	/**
	 * 
	 */
	private JLabel response;
	
	/**
	 * 
	 */
	private final Timer timer;
	
	/**
	 * 
	 */
	private final JSlider slider;
	
	/**
	 * 
	 */
	private NPCType type;
	
	/**
	 * 
	 */
	private JProgressBar progressBar;
	
	/**
	 * 
	 */
	private JProgressBar enemyProgressBar;
	
	/**
	 * 
	 */
	private final JPanel panel;
	
	/**
	 * 
	 */
	private JButton button;
	
	/**
	 * 
	 */
	private String step;
	
	/**
	 * 
	 */
	private List<JButton> buttonList;
	
	/**
	 * 
	 */
	private final Fighter fighter;

	/**
	 * 
	 */
	public SpaceTravelView() {
		presenter = new SpaceTravelPresenter();
		prompt = new JLabel(presenter.getPrompt(NPCType.PIRATE));
		step = "";
		fighter = new Fighter(25, 6, 100);
		
		final TimerWatch listener = new TimerWatch();
		
		timer = new Timer(5, listener);
		listener.setTimer(timer);
		
		setLayout(new BorderLayout(0, 0));
		
		panel = new JPanel();
		ImageIcon icon = new ImageIcon("src\\View\\gnaticon.jpg");
		
		add(panel, BorderLayout.SOUTH);
		
		final JPanel panel_M = new JPanel();
		panel_M.add(new InteractPanel());
		
		add(panel_M, BorderLayout.CENTER);
		
		final JPanel panel_T = new JPanel();
		slider = new JSlider();
		slider.setMaximum(presenter.getNumberofInteractions());
		slider.setSnapToTicks(true);
		slider.setPaintTicks(true);
		slider.setPaintLabels(true);
		slider.setEnabled(false);
		panel_T.setLayout(new GridLayout(2, 1, 0, 0));
		panel_T.setBackground(new Color(255, 0, 0));
		panel_T.add(slider);
		JLabel label = new JLabel(icon);
		final JPanel panelB = new JPanel();
		final FlowLayout flowLayout = (FlowLayout) panelB.getLayout();
		flowLayout.setVgap(0);
		flowLayout.setHgap(0);
		panelB.add(label);
		icon = new ImageIcon("src\\View\\pirateshipicon.jpg");
		label = new JLabel(icon);
		panelB.add(label);
		panel_T.add(panelB);
		add(panel_T, BorderLayout.NORTH);
		transition();
	}
	
	public void generateOptions(JPanel panel){
		buttonList = new LinkedList<JButton>();
		panel.removeAll();
		panel.repaint();
		final List<Actions> npc = presenter.getAction(type);
		for(int count = 0; count < npc.size(); count++){
			button = new JButton("" + npc.get(count));
			buttonList.add(button);
			button.addActionListener(new ButtonClick("" + npc.get(count).name()));
			panel.add(button);
		}
	}
	
	private void transition(){
		if(presenter.canTransition()){
			this.type = presenter.getInteraction();
			generateOptions(panel);
			prompt.setText(presenter.getPrompt(type));
			response.setText("");
			presenter.setNumberOfTransitions(presenter.getNumberOfTransitions() + 1);
			slider.setValue(presenter.getNumberOfTransitions());
			enemyProgressBar.setValue(100);
		}
		else{
			SpaceTravelGUI.getInstance().setVisible(false);
			GUI.getInstance().setVisible(true);
		}
	}
	
	public void enableAllButtons(boolean val){
		for(JButton button: buttonList){
			button.setEnabled(val);
		}
	}
	
	public boolean hasWon(){
		return enemyProgressBar.getValue() <= 0;
	}
	
	public boolean hasLost(){
		return progressBar.getValue() <= 0;
	}
	
	protected void paintComponent(Graphics g){
		super.paintComponent(g);
		BufferedImage image = null;
		try{
			image = ImageIO.read(new File("src\\View\\gnaticon.jpg"));
		}
		catch(IOException e){
			System.out.println(e.getMessage());
			}
			
		g.drawImage(image, 0, 0, null);
	}
	
	private class TimerWatch implements ActionListener{
		/**
		 * 
		 */
		private Timer timer;

		public void setTimer(Timer timer){
			this.timer = timer;
		}
		
		@Override
		public void actionPerformed(ActionEvent arg0) {
			timer.stop();
			enableAllButtons(true);
			
			if(step.equals("WAIT")){
				response.setText("");
				step = "";
			}
			else if(step.equals("ATTACK")){
				final int damage = type.getNPC().attack();
				fighter.takeDamage(damage);
				progressBar.setValue(fighter.getHealth());
				response.setText("The opponent dealt " + damage + " points of damage!");
				enableAllButtons(false);
				
				if(hasLost()){
					JOptionPane.showMessageDialog(null, "You have been defeated an" +
							"d give up 1/4 of your money and cargo to escape");
					SpaceTravelGUI.getInstance().setVisible(false);
					GUI.getInstance().setVisible(true);
				}
				else{
					step = "EMPTY";
					timer.setInitialDelay(1500);
					timer.start();
				}

			}
			else if(step.equals("EMPTY")){
				response.setText("");
			}
			
			else if(step.equals("WIN")){
				enableAllButtons(false);
				final Random rand = new Random();
				final int money = rand.nextInt(70) + 20;
				Player.getInstance().setCredits(Player.getInstance()
				        .getCredits() + money);
				response.setText("You defeated the opponent and obtained $" + money);
				step = "";
				timer.setInitialDelay(2500);
				timer.start();
			}
			else {
				transition();
			}
			
		}
		
		@Override
		public String toString(){
			return super.toString();
		}
		
	}
	
	private class ButtonClick implements ActionListener {
		/**
		 * 
		 */
		private final String name;

		public ButtonClick(String name) {
			this.name = name;
		}

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if(name.equals("ATTACK")){
				enableAllButtons(false);
				attack();
			}
			else if(name.equals("BRIBE")){
				enableAllButtons(false);
				bribe();

			}
			else if(name.equals("SURRENDER")){
				enableAllButtons(false);
				surrender();
			}
			else if(name.equals("FLEE")){
				enableAllButtons(false);
				flee();
			}
			else if(name.equals("IGNORE")){
				enableAllButtons(false);
				ignore();
			}
			
		}
		
		private void attack(){
			final int damage = fighter.fastAttack();
			enemyProgressBar.setValue(enemyProgressBar.getValue() - damage);
			response.setText("You dealt " + damage + " points of damage");
			if(hasWon()){
				step = "WIN";
			}
			else {
				step = "ATTACK";
			}

			timer.setInitialDelay(1500);
			timer.start();
		}
		
		private void ignore(){
			final Random rand = new Random();
			JButton b = null;
			for(JButton button: buttonList){
				if(button != null && button.getText().equals("IGNORE")){
					b = button;
					button.setEnabled(false);
				}
			}
			
			buttonList.remove(b);
			if(rand.nextDouble() < .65){
				response.setText("The officer didn't seem to concerned " +
						"with you. You fly away.");
				timer.setInitialDelay(1500);
				timer.start();
			}
			else {
				response.setText("The officer notices you. You can not escape!");
				timer.setInitialDelay(1500);
				step = "WAIT";
				timer.start();
			}
			
		}
		
		private void flee(){
			final Random rand = new Random();
			if(rand.nextDouble() < .75){
				response.setText("You successfully fled from the opponent");
				timer.setInitialDelay(1500);
				timer.start();
			}
			else {
				response.setText("The flee was not successfull!");
				timer.setInitialDelay(1500);
				step = "WAIT";
				timer.start();
			}
		}
		
		public void bribe(){
			final Random rand = new Random();
			final double money = Player.getInstance().getCredits() * .25;
			final int randNum = rand.nextInt(((int) money) - 20) + 20;
			final String message = "You bribe the police officer, and give them $" + randNum;
			response.setText(message);
			Player.getInstance().setCredits(Player.getInstance().getCredits() - randNum);
			step = "";
			timer.setInitialDelay(1500);
			timer.start();
		}
		
		public void surrender(){
			final Random rand = new Random();
			final List<MarketPlaceItem> list = Player.getInstance().getShip().getCargoItems();
			if(list.size() != 0){
				final MarketPlaceItem item = list.get(rand.nextInt(list.size()));
			
				final int num = rand.nextInt(item.getQuantity());
				item.setQuantity(item.getQuantity() - num);
				
				if(item.getQuantity() == 0){
					response.setText("The pirate felt bad for you and allowed you to leav" +
							"e without giving anything up");
				}
				else {
					response.setText("You have decided to surrender. You opponenet has ta" +
							"ken " + num + " " + item.getName() + " from your cargo!");
				}
			}
			else {
				response.setText("The pirate felt bad for you and allowed you to leave " +
						"without giving anything up");
			}
			
			timer.setInitialDelay(1500);
			timer.start();
		}
		
		@Override
		public String toString(){
			return super.toString();
		}
	}
	
	private class InteractPanel extends JPanel {

		/**
		 * Create the panel.
		 */
		public InteractPanel() {
			setLayout(new GridLayout(2, 0, 0, 0));
			
			final JPanel panel = new JPanel();
			add(panel);
			panel.setLayout(new GridLayout(0, 2, 5, 5));
			
			final JLabel lblEnemyHealth = new JLabel("Enemy Health: ");
			panel.add(lblEnemyHealth);
			
			enemyProgressBar = new JProgressBar();
			panel.add(enemyProgressBar);
			enemyProgressBar.setValue(100);
			
			final JLabel lblHealth = new JLabel("Health: ");
			panel.add(lblHealth);
			
			progressBar= new JProgressBar();
			panel.add(progressBar);
			progressBar.setValue(100);
			
			final JPanel panel_1 = new JPanel();
			add(panel_1);
			panel_1.setLayout(new GridLayout(2, 1, 0, 0));
			
			final JPanel panel_3 = new JPanel();
			panel_1.add(panel_3);
			
			panel_3.add(prompt);
			
			final JPanel panel_4 = new JPanel();
			panel_1.add(panel_4);
			panel_4.add(response);

		}
	}
}
